package com.lft.juc08.blockingqueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * Function: 		A {@code TestBlockingQueue} 阻塞队列.<br/>
 * Reason:   		ADD REASON.<br/>
 * Date:            2021-01-30 23:18<br/>
 * <p>
 * Class Name:      TestBlockingQueue<br/>
 * Package Name:    com.lft.juc08.blockingqueue<br/>
 * @author Laifengting / E-mail:laifengting@foxmail.com
 * @version 1.0.0
 * @since JDK 8
 */
public class TestBlockingQueue {
	public static void main(String[] args) throws InterruptedException {
		// test1();
		// test2();
		// test3();
		test4();
	}
	
	/**
	 * 抛出异常
	 */
	public static void test1() {
		// 指定队列大小
		ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
		// java.util.NoSuchElementException
		// 队列空的，调用方法会报没有相应元素异常
		// System.out.println("队首元素是："+blockingQueue.element());
		System.out.println(blockingQueue.add("A"));
		System.out.println("队首元素是："+blockingQueue.element());
		System.out.println(blockingQueue.add("B"));
		System.out.println("队首元素是："+blockingQueue.element());
		System.out.println(blockingQueue.add("C"));
		System.out.println("队首元素是："+blockingQueue.element());
		// java.lang.IllegalStateException: Queue full 队列满——非法状态异常。
		// 队列满了继续往里添加元素。
		// System.out.println(blockingQueue.add("D"));
		
		System.out.println("-========================-");
		System.out.println("队首元素是："+blockingQueue.element());
		System.out.println(blockingQueue.remove());
		System.out.println("队首元素是："+blockingQueue.element());
		System.out.println(blockingQueue.remove());
		System.out.println("队首元素是："+blockingQueue.element());
		System.out.println(blockingQueue.remove());
		
		// java.util.NoSuchElementException 没有相应元素异常。
		// 队列空了继续查看队首元素时候会报异常。
		// System.out.println("队首元素是："+blockingQueue.element());
		// java.util.NoSuchElementException 没有相应元素异常。
		// 队列空了继续往外取元素。
		// System.out.println(blockingQueue.remove());
	}
	
	/**
	 * 有返回值，不抛出异常
	 */
	public static void test2() {
		// 指定队列大小
		ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
		System.out.println("队首元素是："+blockingQueue.peek());
		System.out.println(blockingQueue.offer("A"));
		System.out.println("队首元素是："+blockingQueue.peek());
		System.out.println(blockingQueue.offer("B"));
		System.out.println("队首元素是："+blockingQueue.peek());
		System.out.println(blockingQueue.offer("C"));
		System.out.println("队首元素是："+blockingQueue.peek());
		// 队列满了，继续添加时，返回 false 不抛出异常！
		System.out.println(blockingQueue.offer("D"));
		
		System.out.println("-========================-");
		System.out.println("队首元素是："+blockingQueue.peek());
		System.out.println(blockingQueue.poll());
		System.out.println("队首元素是："+blockingQueue.peek());
		System.out.println(blockingQueue.poll());
		System.out.println("队首元素是："+blockingQueue.peek());
		System.out.println(blockingQueue.poll());
		System.out.println("队首元素是："+blockingQueue.peek());
		// 队列空了，继续往外取，返回 null 不抛出异常！
		System.out.println(blockingQueue.poll());
	}
	
	/**
	 * 等待，阻塞（一真阻塞）
	 */
	public static void test3() throws InterruptedException {
		// 指定队列大小
		ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
		blockingQueue.put("A");
		blockingQueue.put("B");
		blockingQueue.put("C");
		// 队列满时，没有位置就会一直阻塞。
		// blockingQueue.put("D");
		
		System.out.println(blockingQueue.take());
		System.out.println(blockingQueue.take());
		System.out.println(blockingQueue.take());
		// 队列空时，没有元素就会一直阻塞。
		// blockingQueue.take();
	}
	
	/**
	 * 等待，阻塞（等待超时）
	 */
	public static void test4() throws InterruptedException {
		// 指定队列大小
		ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
		
		blockingQueue.offer("A", 1, TimeUnit.SECONDS);
		blockingQueue.offer("B", 2, TimeUnit.SECONDS);
		blockingQueue.offer("C", 2, TimeUnit.SECONDS);
		// 队列满时，等待2秒，就退出。
		blockingQueue.offer("D", 2, TimeUnit.SECONDS);
		
		System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
		System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
		System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
		// 队列空时，等待2秒，然后就返回null
		System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
		System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));
	}
}
